package com.gofaraway.service.export.factroy;

import com.alibaba.fastjson.JSON;
import com.gofaraway.common.annotation.ExcelHandle;
import com.gofaraway.service.export.service.AbstractExcelService;
import com.gofaraway.service.export.service.AbstractExportExcelService;
import com.gofaraway.service.export.service.AbstractImportExcelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * excel处理工厂
 *
 * @author ChenPeng
 * @Date 2024/5/14 17:07
 */
@Slf4j
@Component
public final class ExcelHandleFactory implements ApplicationContextAware, InitializingBean {


    public static final String DEFAULT_PARAMETER = "excelType";
    /**
     * 策略类工厂map
     */
    public static final Map<String, Class<AbstractExcelService>> STRATEGY_BEAN_MAP = new HashMap<>(16);

    /**
     * 导出策略map
     */
    public static final Map<String, Class<AbstractExportExcelService>> EXPORT_STRATEGY_MAP = new HashMap<>(16);

    /**
     * 导入策略map
     */
    public static final Map<String, Class<AbstractImportExcelService>> IMPORT_STRATEGY_MAP = new HashMap<>(16);

    public static final Map<String, String> IMPORT_STRATEGY_TYPE = new HashMap<>(16);

    @Resource
    private ApplicationContext applicationContext;

    private static ExcelHandleFactory instance;

    @PostConstruct
    public void init() {
        instance = this;
        instance.applicationContext = this.applicationContext;
    }


    /**
     * 工厂初始化
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, Object> orderStrategyMap = applicationContext.getBeansWithAnnotation(ExcelHandle.class);

        orderStrategyMap.forEach((k, v) -> {
            Class<AbstractExcelService> excelServiceClass = (Class<AbstractExcelService>) v.getClass();
            String type = excelServiceClass.getAnnotation(ExcelHandle.class).value().trim().toLowerCase();
            STRATEGY_BEAN_MAP.put(type, excelServiceClass);
        });

        Map<String, AbstractExportExcelService> exportExcelServiceMap = applicationContext.getBeansOfType(AbstractExportExcelService.class);
        exportExcelServiceMap.forEach((key, value) -> {
            String type = value.getClass().getAnnotation(ExcelHandle.class).value().trim().toLowerCase();
            EXPORT_STRATEGY_MAP.put(type, (Class<AbstractExportExcelService>) value.getClass());
        });

        Map<String, AbstractImportExcelService> importExcelServiceMap = applicationContext.getBeansOfType(AbstractImportExcelService.class);
        importExcelServiceMap.forEach((key, value) -> {
            ExcelHandle annotation = value.getClass().getAnnotation(ExcelHandle.class);
            String type = annotation.value().trim().toLowerCase();
            IMPORT_STRATEGY_MAP.put(type, (Class<AbstractImportExcelService>) value.getClass());
            IMPORT_STRATEGY_TYPE.put(type, annotation.importType());
        });
    }

    /**
     * 获取导出执行器
     *
     * @param excelType
     * @return
     */
    public static AbstractExportExcelService getExportExcelService(String excelType) {
        Class<AbstractExportExcelService> excelServiceClass = EXPORT_STRATEGY_MAP.get(excelType.toLowerCase());
        if (excelServiceClass == null) {
            log.error("未找到对应处理器 >>> excelType:{}", excelType);
            throw new IllegalArgumentException("没有对应的Excel处理器");
        }
        return instance.applicationContext.getBean(excelServiceClass);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("strategyBeanMap size:{},strategyBeanMap:{}", STRATEGY_BEAN_MAP.size(), JSON.toJSONString(STRATEGY_BEAN_MAP.keySet()));
    }
}
